package com.ys.chatserver.http.logic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.Processor;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ys.chatserver.common.dto.cnst.RetResult;
import com.ys.chatserver.http.logic.dto.*;
import com.ys.chatserver.tool.EmptyUtils;

import java.util.*;
import java.util.stream.Collectors;

public class StructureUserProccessor implements SysActionConst, Processor {

    private Gson gson = new Gson();

    @Override
    public Object process(int job_dispatch_id, int action_id, Object newData, Object oldData, User user) throws Exception {
        Object ret = null;
        String newDataJSON = (String) newData;

        if (job_dispatch_id == JobDispatchConst.LOGIC_GROUP_STRUCTURE_USER) {
            ret = maintainJobDispatcher(action_id, newDataJSON, oldData, user);
        } else {
            throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
        return ret;
    }

    private Object maintainJobDispatcher(int actionId, String newDataJSON, Object oldData, User user) throws Exception {

        switch (actionId) {
            case ACTION_ADD_STRUCTURE_USER: {//添加组织下用户
                JSONObject jsonObject = JSON.parseObject(newDataJSON);
                String structureNo = jsonObject.getString("structureNo");
                String userUids = jsonObject.getString("userUids");
                List<String> list = EmptyUtils.getListObjectSplitValue(userUids);
                return addStructureUser(list, structureNo);
            }
            case ACTION_QUERY_STRUCTURE_USER: {//查询用户所在组织
                return queryStructureUser(user.getUserId());
            }
            case ACTION_QUERY_STRUCTURE_USER_INFO: {//查询组织用户列表(组织编号)
                JSONObject jsonObject = JSON.parseObject(newDataJSON);
                String structureNo = jsonObject.getString("structureNo");
                StructureUserVo vo = new StructureUserVo();
                vo.setStructure(queryStructure(structureNo));
                vo.setUser(queryUserInfos(structureNo));
                return gson.toJson(RetResult.successResult("查询成功！", vo));
            }
            case ACTION_QUERY_STRUCTURE_USER_BY_ID: {//查询用户可见组织人员列表
                JSONObject jsonObject = JSON.parseObject(newDataJSON);
                String userName = jsonObject.getString("userName");
                String userId = user.getUserId();
                return queryUserInfoById(userId, userName);
            }
            case ACTION_UPDATE_STRUCTURE_USER: {
                List<StructureUserInfoVO> infos = gson.fromJson(newDataJSON, new TypeToken<List<StructureUserInfoVO>>() {
                });
                return updateStructureUser(infos);
            }
            case ACTION_DELETE_STRUCTURE_USER: {//删除用户组织
                JSONObject jsonObject = JSON.parseObject(newDataJSON);
                String structureNo = jsonObject.getString("structureNo");
                String userUids = jsonObject.getString("userUids");
                List<String> list = EmptyUtils.getListObjectSplitValue(userUids);
                return deleteStructureUser(list, structureNo);
            }
            case ACTION_QUERY_NOT_STRUCTURE_USER_INFO: {//获取不在组织下的用户列表
                return queryNotStructureUserInfo();
            }
            case ACTION_QUERY_STRUCTURE_ALL_USER: {
                String userId = user.getUserId();
                return queryUserInfoById(userId);
            }
            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(actionId);
        }
    }

    private String queryUserInfoById(String userId, String userName) throws Exception {
        String sql = "select user_uid,user_mail,nickname,is_online," +
                "user_avatar_file_name,account_type,user_type from g_users where del_flag = 0 and user_uid in " +
                "(select user_id from structure_user_info where structure_no in " +
                "(select structure_no from structure_info where structure_level " +
                "like concat ('%',(select structure_no from structure_user_info " +
                "where user_id='" + userId + "' and user_type='" + CaseUserType.USER.name() + "'),'%'))) and user_uid != '" + userId + "' " +
                "and user_type='" + CaseUserType.USER.name() + "'";

        if (!CommonUtils.isStringEmpty(userName)) {
            sql += " and nickname like '%" + userName + "%'";
        }

        return gson.toJson(RetResult.successResult("查询成功!", getUserList(sql)));
    }

    public String queryUserInfoById(String userId) throws Exception {
        String sql = "select user_uid,user_mail,nickname,is_online," +
                "user_avatar_file_name,account_type,user_type from g_users where del_flag = 0 and user_uid in " +
                "(select user_id from structure_user_info where structure_no in " +
                "(select structure_no from structure_info where structure_level " +
                "like concat ('%',(select structure_no from structure_user_info " +
                "where user_id='" + userId + "' and user_type='" + CaseUserType.USER.name() + "'),'%'))) " +
                "and user_type='" + CaseUserType.USER.name() + "'";

        return gson.toJson(RetResult.successResult("查询成功!", getUserList(sql)));
    }

    private String queryNotStructureUserInfo() throws Exception {
        //查询不在组织的用户,用于添加到组织里面(设备不查询只查询user_type = 0的数据)
        String sql = "SELECT user_uid,user_mail,nickname,is_online," +
                "user_avatar_file_name,account_type,user_type FROM g_users " +
                "WHERE del_flag = 0 and user_type = 0 and account_type=1 and user_uid not IN " +
                "(SELECT user_id FROM `structure_user_info`)";
        return gson.toJson(RetResult.successResult("查询成功!", getUserList(sql)));
    }

    public List<UserInfoVO> getUserList(String sql) throws Exception {
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        List<UserInfoVO> vos = new ArrayList<>();
        if (!vectors.isEmpty()) {
            for (Vector<?> v : vectors) {
                int i = 0;
                UserInfoVO vo = new UserInfoVO();
                vo.setUserUid(v.get(i).toString());
                vo.setUserMail(v.get(++i).toString());
                vo.setNickname(v.get(++i).toString());
                vo.setIsOnline(Integer.valueOf(v.get(++i).toString()));
                vo.setUserAvatarFileName(v.get(++i).toString());
                vo.setAccountType(Integer.parseInt(v.get(++i).toString()));
                vo.setUserType(Integer.parseInt(v.get(++i).toString()));
                vos.add(vo);
            }
        }
        return vos;
    }

    private String updateStructureUser(List<StructureUserInfoVO> infos) throws Exception {
        Map<String, List<StructureUserInfoVO>> map = infos.stream()
                .collect(Collectors.groupingBy(StructureUserInfoVO::getStructureNo));

        for (Map.Entry<String, List<StructureUserInfoVO>> entry : map.entrySet()) {
            String key = entry.getKey();
            List<StructureUserInfoVO> value = entry.getValue();

            List<String> list = new ArrayList<>();
            String sql = "delete from structure_user_info  where structure_no = '" + key + "';";
            list.add(sql);
            LogicProcessor2.db.update(list, true);

            addStructureUser(value);
        }
        return gson.toJson(RetResult.successResult("新增成功!"));
    }

    private String deleteStructureUser(List<String> userList, String structureNo) throws Exception {
        List<String> list = new ArrayList<>();
        for (String str : userList) {
            if (exitStructureNoUser(str, structureNo)) {
                String sql = "delete from structure_user_info where " +
                        "user_id ='" + str + "';";
                list.add(sql);
            }
        }
        if (list.size() == 0) {
            return gson.toJson(RetResult.successResult("用户不存在组织下，删除失败!"));
        }
        boolean update = LogicProcessor2.db.update(list, true);
        return update ? gson.toJson(RetResult.successResult("删除成功!")) :
                gson.toJson(RetResult.failResult("删除失败!系统异常!"));

    }

    private List<UserInfoVO> queryUserInfos(String structureNo) throws Exception {
        String sql = "SELECT user_uid,user_mail,nickname,is_online," +
                "user_avatar_file_name,account_type,user_type FROM g_users WHERE user_uid IN " +
                "(SELECT user_id FROM `structure_user_info`" +
                " WHERE structure_no = '" + structureNo + "' and user_type='USER')";
        return getUserList(sql);
    }


    private List<StructureInfoVO> queryStructure(String structureNo) throws Exception {
        String sql = "select structure_no,structure_name,structure_level,creator_id,creator_name," +
                "parent_no,structure_type from structure_info where parent_no='" + structureNo + "' and parent_no!=structure_no";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        List<StructureInfoVO> vos = new ArrayList<>();
        if (!vectors.isEmpty()) {
            for (Vector<?> v : vectors) {
                int i = 0;
                StructureInfoVO vo = new StructureInfoVO();
                vo.setStructureNo(v.get(i).toString());
                vo.setStructureName(v.get(++i).toString());
                vo.setStructureLevel(v.get(++i).toString());
                vo.setCreatorId(v.get(++i).toString());
                vo.setCreatorName(v.get(++i).toString());
                vo.setParentNo(v.get(++i).toString());
                vo.setStructureType(Integer.valueOf(v.get(++i).toString()));
                vos.add(vo);
            }
        }
        return vos;
    }

    private String queryStructureUser(String userId) throws Exception {
        //查询本级所有人
        List<StructureUserInfoVO> list = queryUserList(userId);
        if (list.isEmpty()) {
            return gson.toJson(RetResult.failResult("用户不存在!"));
        }

        //查询本级及上面所有组织树
        String structureNo = list.get(0).getStructureNo();
        StructureInfoVO v = getStructure(structureNo);
        if (Objects.isNull(v)) {
            return gson.toJson(RetResult.failResult("用户不在组织下!"));
        }

        List<StructureInfoVO> vos = getStructureTree(v.getStructureLevel());
        List<StructureInfoVO> infos = vos.stream()
                .filter(i -> i.getParentNo().equals(i.getStructureNo()))
                .collect(Collectors.toList());
        StructureInfoVO vo = infos.get(0);
        StructureInfoVO sv = obtainStructuresTree(vos, vo);

        return gson.toJson(RetResult.successResult("查询成功!", sv));

    }

    private StructureInfoVO obtainStructuresTree(List<StructureInfoVO> vos,
                                                 StructureInfoVO vo) {
        List<StructureInfoVO> list = new ArrayList<>();
        for (StructureInfoVO v : vos) {
            if (v.getParentNo().equals(vo.getStructureNo())
                    && !v.getParentNo().equals(v.getStructureNo())) {
                list.add(v);

            }
        }
        if (list.size() != 0) {
            vo.setChildList(list);
            for (StructureInfoVO infoVO : vo.getChildList()) {
                obtainStructuresTree(vos, infoVO);
            }
        }
        return vo;
    }

    private List<StructureInfoVO> getStructureTree(String structureLevel) throws Exception {
        String[] strings = structureLevel.split(":");
        List<String> list = new ArrayList<>(Arrays.asList(strings));
        return queryByNos(list);
    }

    private List<StructureInfoVO> queryByNos(List<String> list) throws Exception {
        StringBuilder querySql = new StringBuilder("select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,structure_type from structure_info where structure_no in ('");

        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if (i == list.size() - 1) {
                querySql.append(s).append("');");
            } else {
                querySql.append(s).append("','");
            }
        }
        return getStructureInfoVOS(querySql.toString());
    }

    private List<StructureInfoVO> getStructureInfoVOS(String querySql) throws Exception {
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(querySql);
        List<StructureInfoVO> vos = new ArrayList<>();
        if (vectors.isEmpty()) {
            return vos;
        }

        for (Vector<?> v : vectors) {
            int i = 0;
            StructureInfoVO vo = new StructureInfoVO();
            vo.setStructureNo(v.get(i).toString());
            vo.setStructureName(v.get(++i).toString());
            vo.setStructureLevel(v.get(++i).toString());
            vo.setCreatorId(v.get(++i).toString());
            vo.setCreatorName(v.get(++i).toString());
            vo.setParentNo(v.get(++i).toString());
            vo.setStructureType(Integer.valueOf(v.get(++i).toString()));
            vos.add(vo);
        }
        return vos;
    }

    private StructureInfoVO getStructure(String structureNo) throws Exception {
        String sql = "select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,structure_type from structure_info " +
                "where structure_no = '" + structureNo + "';";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);

        if (vectors.isEmpty()) {
            return null;
        }

        StructureInfoVO vo = new StructureInfoVO();
        for (Vector<?> v : vectors) {
            int i = 0;
            vo.setStructureNo(v.get(i).toString());
            vo.setStructureName(v.get(++i).toString());
            vo.setStructureLevel(v.get(++i).toString());
            vo.setCreatorId(v.get(++i).toString());
            vo.setCreatorName(v.get(++i).toString());
            vo.setParentNo(v.get(++i).toString());
            vo.setStructureType(Integer.valueOf(v.get(++i).toString()));
        }
        return vo;
    }

    private List<StructureUserInfoVO> queryUserList(String userId) throws Exception {
        List<StructureUserInfoVO> vos = new ArrayList<>();

        String sql = "SELECT structure_no,user_id,user_type FROM structure_user_info WHERE structure_no IN " +
                "(SELECT structure_no FROM `structure_user_info` WHERE user_id = '" + userId + "');";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        if (vectors.isEmpty()) {
            return vos;
        }
        for (Vector<?> v : vectors) {
            int i = 0;
            StructureUserInfoVO vo = new StructureUserInfoVO();
            vo.setStructureNo(v.get(i).toString());
            vo.setUserId(v.get(++i).toString());
            vo.setUserType(v.get(++i).toString());

            vos.add(vo);
        }
        return vos;
    }

    private String addStructureUser(List<StructureUserInfoVO> infos) throws Exception {
        List<String> list = new ArrayList<>();
        for (StructureUserInfoVO info : infos) {
            String sql = "insert into structure_user_info (structure_no,user_id,user_type) values " +
                    "('" + info.getStructureNo() + "','" + info.getUserId() + "','" + info.getUserType() + "');";
            list.add(sql);
        }

        boolean update = LogicProcessor2.db.update(list, true);
        return update ? gson.toJson(RetResult.successResult("添加成功!")) : gson.toJson(RetResult.failResult("添加失败!系统异常!"));
    }

    public String addStructureUser(List<String> userList, String structureNo) throws Exception {
        List<String> list = new ArrayList<>();
        for (String str : userList) {
            if (!exitStructureNoByUser(str)) {
                String sql = "insert into structure_user_info (structure_no,user_id) values " +
                        "('" + structureNo + "','" + str + "');";
                list.add(sql);
            }
        }
        if (list.isEmpty()) {
            return gson.toJson(RetResult.failResult("用户已绑定组织,添加失败！"));
        } else {
            boolean update = LogicProcessor2.db.update(list, true);
            return update ? gson.toJson(RetResult.successResult("添加成功!")) : gson.toJson(RetResult.failResult("添加失败!系统异常!"));
        }
    }

    /**
     * 判断用户是否绑定组织
     *
     */
    public Boolean exitStructureNoByUser(String userId) throws Exception {
        String sql = "select * from structure_user_info where user_id='" + userId + "'";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        return !vectors.isEmpty();
    }

    /**
     * 判断组织下用户是否存在
     *
     */
    public Boolean exitStructureNoUser(String userId, String structureNo) throws Exception {
        String sql = "select * from structure_user_info where user_id='" + userId + "' and structure_no='" + structureNo + "'";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        return !vectors.isEmpty();
    }


}
